package com.mm.cloud.common.security.helper;

import com.alibaba.fastjson.JSONObject;
import com.mm.cloud.common.redis.constant.RedisKeySystemConstants;
import com.mm.cloud.common.redis.service.IRedisService;
import com.mm.cloud.common.redis.util.RedisKeyStringUtils;
import com.mm.cloud.common.core.constant.SecurityConstants;
import com.mm.cloud.common.core.enums.ExceptionEnum;
import com.mm.cloud.common.core.exception.BaseException;
import com.mm.cloud.common.core.util.SpringUtils;
import com.mm.cloud.common.security.loginuser.LoginUser;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Objects;
import java.util.UUID;

/**
 * 权限工具类
 *
 * @author mr
 * @since 2021-07-10
 */
@Slf4j
public class LoginUserHelper {

    private static final ThreadLocal<LoginUser> THREAD_LOCAL = new ThreadLocal<>();

    /**
     * 生成BCryptPasswordEncoder密码
     *
     * @param password 密码
     * @return 加密字符串
     */
    public static String encryptPassword(String password) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.encode(password);
    }

    /**
     * 判断密码是否相同
     *
     * @param rawPassword     真实密码
     * @param encodedPassword 加密后字符
     * @return 结果
     */
    public static boolean matchesPassword(String rawPassword, String encodedPassword) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }

    /**
     * 创建token
     */
    public static String createToken() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 获取token
     */
    public static String getToken() {
        return getRequest().getHeader(SecurityConstants.SECURITY_TOKEN);
    }

    /**
     * 获取request
     */
    public static HttpServletRequest getRequest() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        Assert.notNull(attributes, "attributes is null");
        return ((ServletRequestAttributes) attributes).getRequest();
    }

    /**
     * 获取登录用户
     *
     * @return
     */
    public static LoginUser getLoginUser() {
        try {
            LoginUser loginUser = THREAD_LOCAL.get();
            if (Objects.nonNull(loginUser)) {
                return loginUser;
            }
            final String token = getToken();
            if (StringUtils.isEmpty(token)) {
                throw new BaseException(ExceptionEnum.TOKEN_INVALID);
            }
            IRedisService redisService = SpringUtils.getApplicationContext().getBean(IRedisService.class);
            Object o = redisService.get(RedisKeyStringUtils.appendRedisKey(RedisKeySystemConstants.REDIS_TOKEN, token));
            if (Objects.isNull(o)) {
                throw new BaseException(ExceptionEnum.TOKEN_INVALID);
            }
            loginUser = ((JSONObject) o).toJavaObject(LoginUser.class);
            THREAD_LOCAL.set(loginUser);
            return loginUser;
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BaseException(ExceptionEnum.TOKEN_INVALID);
        }
    }

    /**
     * 清空本地缓存
     */
    public static void cleanLoginUser() {
        THREAD_LOCAL.remove();
    }


}
